<template>
  <div class='chat'>
    <div class="shopname">
      <div class="left">{{shopinfo?.shop_name}}</div>
      <div class="right">
        <div class="tel" @click="showActionSheet = true">
          <van-icon :name="require('@/assets/img/message/tel.png')" fit="cover" />
          <div class="text">电话</div>
        </div>
        <div class="shop" @click="openShop">
          <van-icon :name="require('@/assets/img/message/shop.png')" fit="cover" />
          <div class="text">店铺</div>
        </div>
      </div>
    </div>
    <div class="msg-list" ref="msgList">
      <van-pull-refresh v-model="isLoadHistory" @refresh="onLoadHistory" :disabled="finished">
        <ul ref="msgContentList">
          <li class="msg-item" :class="{my:item.type==1}" v-for="(item,index) in msgList" :key="index">
            <van-image round width="36" height="36" fit="cover" :src="item.type==1?`${resourceURL}${userinfo?.avatar}`:servicePic" />
            <div class="content">{{item.msg}} </div>
          </li>
        </ul>
      </van-pull-refresh>
    </div>
    <div class="send">
      <van-field v-model="msg" :border="false" round />
      <van-button type="primary" size="small" round @click="send" :loading="isSend">发送</van-button>
    </div>

    <van-action-sheet v-model="showActionSheet " :actions="actions" cancel-text="取消" close-on-click-action @cancel="showActionSheet = false" @select="onSelect" />
  </div>
</template>

<script>
import { Toast, Notify, Dialog } from "vant";

export default {
  data () {
    return {
      // obj: JSON.parse(this.$route.query._chat),
      userinfo: this.$store.state.userInfo,
      socketUrl: "ws://111.230.171.153:8084",
      servicePic: require("@/assets/img/chat/cs.png"),
      obj: {},
      actions: [{ name: "" }],
      msgList: [],
      msg: "",
      showActionSheet: false,
      websock: "",
      chatToken: "",
      isLoadHistory: false,
      finished: false,
      token: "",
      isSend: false,
      socket: null,
      pageIndex: 1,
      lockReconnect: false,
      isOnline: false,
      networkStatus: true,
      cm_id: null,
      shop_id: null,
      shopinfo: {},
    };
  },
  created () {
    //页面刚进入时开启长连接
    this.shop_id = this.$route.query.shop_id;
    this.isOnline = window.navigator.onLine;
    if (this.isOnline) {
      this.createWebSocket();
    } else {
      Notify({
        type: "danger",
        message: "网络不可用",
        duration: 0,
      });
    }
    this.getShopinfo();
  },
  mounted () {
    window.addEventListener("online", this.monitorNetworkStatus);
    window.addEventListener("offline", this.monitorNetworkStatus);
  },
  destroyed () {
    if (this.socket) this.socket.close();
    this.timeReconnect && clearTimeout(this.timeReconnect);
    window.removeEventListener("online", this.monitorNetworkStatus);
    window.removeEventListener("offline", this.monitorNetworkStatus);
  },
  methods: {
    // 获取店铺详情
    getShopinfo () {
      this.$axios
        .get(this.$api.shopinfo, {
          params: {
            shop_id: this.shop_id,
          },
        })
        .then((res) => {
          if (res.data.code == 1) {
            this.shopinfo = res.data.data;
            if (this.shopinfo.imagesurl)
              this.servicePic = this.resourceURL + this.shopinfo.imagesurl;
            this.actions[0].name = this.shopinfo.shop_phone;
          }
        });
    },
    // 加载历史
    onLoadHistory () {
      const { scrollHeight } = this.$refs.msgContentList;
      this.getMessageList(() => {
        this.$nextTick(() => {
          this.isLoadHistory = false;
          const msgListDom = this.$refs.msgList;
          const { scrollHeight: msgListScrollHeight } = msgListDom;
          msgListDom.scrollTop = msgListScrollHeight - scrollHeight - 40;
        });
      });
    },
    // 获取聊天室专属token
    getChatToken (string) {
      this.$axios
        .get(this.$api.chatroomtoken, {
          params: {
            // shop_id: this.obj.shop_id,
            shop_id: this.shop_id,
            string,
          },
        })
        .then((res) => {
          if (res.data.code == 1) {
            this.token = res.data.data.token;
            this.cm_id = res.data.data.cm_id;
            this.getMessageList();
          } else if (res.data.code == -1) {
            Dialog.alert({
              message: res.data.msg,
            }).then(() => {
              // on close
              this.$router.go(-1);
            });
          }
        });
    },
    // 监听网络状态
    monitorNetworkStatus (e) {
      this.lockReconnect = e.type == "offline";
      if (!this.lockReconnect) {
        this.createWebSocket();
      } else {
        Notify({
          type: "danger",
          message: "网络不可用",
          duration: 0,
        });
      }
    },
    // 建立连接
    initWebSocket () {
      this.socket.onopen = (e) => {
        Notify.clear();
        console.log("连接成功", e);
      };
      this.socket.onmessage = (res) => {
        const data = JSON.parse(res.data);
        if (data.code == 1) {
          this.msgList.push({ type: 1, msg: this.msg });
          this.msg = "";
        } else if (data.code == -1) {
          Toast("发送失败");
        } else if (data.code == 2) {
          this.msgList.push({ type: 2, msg: data.msg });
        } else {
          this.getChatToken(data.string);
        }
        this.isSend = false;
        this.autoScrollButtom();
      };
      this.socket.onclose = (e) => {
        if (!e.code == 1000) this.reconnect();
        console.log("连接关闭", e.code, e.reason, e.wasClean);
      };
      this.socket.onerror = () => {
        this.reconnect();
        console.log("连接失败");
      };
    },
    // 连接 ws
    createWebSocket () {
      try {
        if ("WebSocket" in window) {
          this.socket = new WebSocket(this.socketUrl);
        } else {
          Notify({
            type: "danger",
            message: "您的浏览器不支持websocket协议",
            duration: 0,
          });
        }
        this.initWebSocket();
      } catch (e) {
        this.reconnect();
        console.log(e);
      }
    },
    // 断开自动连接
    reconnect () {
      if (this.lockReconnect) return;
      this.lockReconnect = true;
      //没连接上会一直重连，设置延迟避免请求过多
      this.timeReconnect && clearTimeout(this.timeReconnect);
      this.timeReconnect = setTimeout(() => {
        this.createWebSocket();
        this.lockReconnect = false;
      }, 2000);
    },
    // 打开店铺详情
    openShop () {
      this.$router.push({ name: "store", query: { id: this.shop_id } });
    },
    // 点击电话号码复制
    onSelect (action) {
      let input = document.createElement("input"); // 创建input对象
      input.value = action.name; // 设置复制内容
      document.body.appendChild(input); // 添加临时实例
      input.select(); // 选择实例内容
      document.execCommand("Copy"); // 执行复制
      document.body.removeChild(input); // 删除临时实例
      window.location.href = "tel://" + action.name;
      // Toast("复制成功");
    },
    // 获取聊天室历史消息
    getMessageList (cb) {
      this.$axios
        .get(this.$api.gethistoricaldata, {
          params: {
            page: this.pageIndex,
            limit: 10,
            cm_id: this.cm_id,
          },
        })
        .then((res) => {
          if (res.data.code == 1) {
            let list = res.data.data.data.reverse();
            this.msgList.unshift(...list);
            this.pageIndex++;
            if (list.length < 10) this.finished = true;
            if (!this.isLoadHistory) this.autoScrollButtom();
            cb && cb();
          }
        });
    },
    // 发送消息
    send () {
      if (!this.msg || this.msg.match(/^\s+$/)) {
        return Toast("不能发送空白内容");
      }
      if (this.socket.readyState !== 1) {
        return Toast("发送失败，稍后重试");
      }
      this.isSend = true;
      try {
        this.socket.send(
          JSON.stringify({
            message: this.msg,
            token: this.token,
          })
        );
      } catch (error) {
        this.isSend = false;
        Toast("发送失败");
        console.error(error);
      }
    },
    // 滚动到底部
    autoScrollButtom () {
      this.$nextTick(() => {
        // console.log(document.body.scrollTop);
        const msgListDom = this.$refs.msgList;
        if (!msgListDom) return true;
        const { scrollHeight } = msgListDom;
        msgListDom.scrollTop = scrollHeight;
        window.addEventListener("scroll", this.handleScroll, true);
      });
    },
  },
};
</script>

<style scoped lang='less'>
.chat {
  position: relative;
  height: 100%;
  min-height: calc(100vh - 60px);
  padding-bottom: 60px;
  background-color: #f9f9f9;
  .shopname {
    display: flex;
    justify-content: space-between;
    align-items: center;
    height: 56px;
    color: #303030;
    font-size: 14px;
    padding: 12px 16px;
    background-color: #fff;
    box-sizing: border-box;
    .right {
      display: flex;
      .tel,
      .shop {
        color: #303030;
        text-align: center;
        margin-left: 16px;
        .text {
          font-size: 12px;
          transform: scale(0.9);
        }
      }
    }
  }
  .msg-list {
    padding: 0 16px 20px;
    height: calc(100vh - 56px - 60px);
    overflow: hidden auto;
    box-sizing: border-box;
    .msg-loading {
      text-align: center;
      padding-top: 10px;
    }
    .msg-item {
      display: flex;
      margin-top: 20px;
      .content {
        margin: 0 12px;
        background-color: #fff;
        padding: 12px 16px;
        border-radius: 6px;
        font-size: 14px;
        color: #06021a;
        max-width: 188px;
      }
      &.my {
        flex-direction: row-reverse;
        .content {
          background-color: #b60102;
          color: #fff;
        }
      }
    }
  }
  .send {
    display: flex;
    align-items: center;
    position: fixed;
    left: 0;
    bottom: 0;
    width: 100%;
    height: 54px;
    padding: 8px 16px;
    background-color: #fff;
    box-sizing: border-box;
    .van-field {
      flex: 1;
      padding: 6px 12px;
      border-radius: 20px;
      background-color: #f6f6f6;
    }
    .van-button {
      width: 60px;
      margin-left: 12px;
    }
  }
}
</style>
